'use client'

import { useEffect, useRef, useState } from 'react';
import type { BurnDownInfo, ExtraSpritInfo } from '@/grpc/types';
import { Card, Table } from 'antd';
import type { ColumnsType } from 'antd/lib/table';
import moment from 'moment';
import { useSize } from "ahooks";
import { LineChart, Line, XAxis, YAxis, Tooltip, Legend } from 'recharts';


class DayInfo {
    constructor(day: number) {
        this.day = day;
    }
    day: number;
    remainMinutes?: number;
}

class MemberBurnDownInfo {
    constructor(memberUserId: string, memberDisplayName: string, memberLogoUri: string, dayInfoList: DayInfo[]) {
        this.memberUserId = memberUserId;
        this.memberDisplayName = memberDisplayName;
        this.memberLogoUri = memberLogoUri;
        this.dayInfoList = dayInfoList;
    }
    memberUserId: string;
    memberDisplayName: string;
    memberLogoUri: string;
    dayInfoList: DayInfo[];
}

export interface BurnDownPanelProps {
    spritInfo: ExtraSpritInfo;
    burnDownInfoList: BurnDownInfo[];
}

export function BurnDownPanel(props: BurnDownPanelProps) {
    const [columns, setColumns] = useState<ColumnsType<MemberBurnDownInfo>>([]);
    const [burnDownInfoList, setBurnDownInfoList] = useState<MemberBurnDownInfo[]>([]);
    const domRef = useRef<HTMLDivElement>(null);
    const domRefSize = useSize(domRef);

    const calcColumns = (dayList: number[]) => {
        const tmpColumns: ColumnsType<MemberBurnDownInfo> = [
            {
                title: "用户",
                width: 100,
                render: (row: MemberBurnDownInfo) => (
                    <>
                        {row.memberUserId == "" && <span>总计</span>}
                        {row.memberUserId != "" && <span>{row.memberDisplayName}</span>}
                    </>
                ),
            },
        ];
        dayList.forEach((day, index) => {
            tmpColumns.push({
                title: `${day}`,
                width: 150,
                render: (row: MemberBurnDownInfo) => {
                    const dayInfo = row.dayInfoList[index];
                    return dayInfo.remainMinutes == undefined ? "-" : (dayInfo.remainMinutes / 60).toFixed(2);
                },
            });
        })
        setColumns(tmpColumns);
    };

    const updateTotalValue = (infoList: MemberBurnDownInfo[]) => {
        //找到总计值
        const totalIndex = infoList.findIndex(item => item.memberUserId == "");
        if (totalIndex == -1) {
            return;
        }

        for (const dayInfo of infoList[totalIndex].dayInfoList) {
            let totalRemainMinutes = 0;
            let emptyCount = 0;
            for (const info of infoList) {
                if (info.memberUserId == "") {
                    continue
                }
                for (const memberDayInfo of info.dayInfoList) {
                    if (dayInfo.day == memberDayInfo.day) {
                        if (memberDayInfo.remainMinutes == undefined) {
                            emptyCount += 1;
                        }
                        totalRemainMinutes += memberDayInfo.remainMinutes ?? 0;
                    }
                }
            }
            if (emptyCount == 0) {
                dayInfo.remainMinutes = totalRemainMinutes;
            }
        }

        setBurnDownInfoList(infoList);
    };

    const calcBurnDownInfoList = async () => {
        const tmpDayList: number[] = [];
        //计算工作日
        for (const dayTime = moment(props.spritInfo.startTime ?? 0).startOf("day");
            dayTime <= moment(props.spritInfo.endTime ?? 0).startOf("day");
            dayTime.add(1, "days")) {
            let matchNonWorkDay = false;
            for (const nonWorkDayTime of (props.spritInfo.nonWorkDayList ?? [])) {
                if (dayTime.valueOf() == moment(nonWorkDayTime).startOf("day").valueOf()) {
                    matchNonWorkDay = true;
                    break;
                }
            }
            if (!matchNonWorkDay) {
                tmpDayList.push(parseInt(dayTime.format("YYYYMMDD")));
            }
        }
        const tmpInfoList: MemberBurnDownInfo[] = [];

        const tmpMap: Map<string, number> = new Map();
        const tmpUserIdSet: Set<string> = new Set();

        props.burnDownInfoList.forEach(item => {
            const key = `${item.memberUserId}${item.day}`;
            tmpMap.set(key, item.remainMinutes ?? 0);
            if (!tmpUserIdSet.has(item.memberUserId ?? "")) {
                tmpUserIdSet.add(item.memberUserId ?? "");
                tmpInfoList.push(new MemberBurnDownInfo(item.memberUserId ?? "", item.memberDisplayName ?? "", item.memberLogoUri ?? "", []));
            }
        });
        tmpInfoList.forEach((info, index) => {
            const dayInfoList: DayInfo[] = [];
            for (const day of tmpDayList) {
                const key = `${info.memberUserId ?? ""}${day}`;
                const tmpDayInfo = new DayInfo(day);
                tmpDayInfo.remainMinutes = tmpMap.get(key);
                dayInfoList.push(tmpDayInfo);
            }
            tmpInfoList[index].dayInfoList = dayInfoList;
        });
        //计算累计值
        {
            const dayInfoList: DayInfo[] = [];
            for (const day of tmpDayList) {
                dayInfoList.push(new DayInfo(day));
            }
            tmpInfoList.push(new MemberBurnDownInfo("", "", "", dayInfoList));
        }
        updateTotalValue(tmpInfoList);
        calcColumns(tmpDayList);
    };

    const getChartData = () => {
        if (burnDownInfoList.length == 0) {
            return [];
        }
        const totalInfo = burnDownInfoList[burnDownInfoList.length - 1];
        if (totalInfo.dayInfoList.length == 0) {
            return [];
        }        
        const retList = totalInfo.dayInfoList.map((item, index) => {
            return {
                name: `${item.day}`,
                "实际": item.remainMinutes == undefined ? undefined : item.remainMinutes / 60.0,
            };
        });
        return retList;
    };

    useEffect(() => {
        calcBurnDownInfoList();
    }, []);

    return (
        <>
            <Card title="统计表" headStyle={{ backgroundColor: "#eee" }}>
                <Table rowKey="memberUserId" columns={columns} dataSource={burnDownInfoList} pagination={false}
                    scroll={{ x: "max-content" }} />
            </Card>
            <Card title="燃尽图" headStyle={{ backgroundColor: "#eee" }}>
                <div ref={domRef}>
                    {burnDownInfoList.length > 1 && (
                        <LineChart height={300} width={(domRefSize?.width ?? 600) * 0.95} data={getChartData()}>
                            <XAxis dataKey="name" />
                            <YAxis />
                            <Tooltip />
                            <Legend />
                            <Line type="monotone" dataKey="实际" stroke="orange" />
                        </LineChart>
                    )}
                </div>
            </Card>
        </>
    )
}